package com.sduept.nwld.dataserver.rest;

import com.sduept.bigdata.fault.common.ParamDesc;
import com.sduept.bigdata.fault.entity.FaultRecord;
import com.sduept.bigdata.fault.entity.TravelingWaveFaultRecord;
import com.sduept.bigdata.fault.manager.*;
import com.sduept.bigdata.weather.manager.FaultWeatherInfoManager;
import com.sduept.cim.ledger.manager.EquipmentLedgerManager;
import com.sduept.cim.ledger.manager.SubstationLedgerManager;
import com.sduept.cim.ledger.model.PrimaryEquipmentLedger;
import com.sduept.cim.ledger.model.SubstationLedger;
import com.sduept.cim.model.core.Substation;
import com.sduept.core.ParamManager;
import com.sduept.core.dao.SuperDAO;
import com.sduept.core.entity.SystemParameter;
import com.sduept.bigdata.weather.map.MapDataCache;
import com.sduept.nwld.dataserver.manager.cim.CimManager;
import com.sduept.nwld.dataserver.manager.fault.FaultFeedbackManager;
import com.sduept.nwld.dataserver.model.daily.FaultFeedback;
import com.sduept.permission.entity.PersonnelEntityBean;
import com.sduept.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author laiy
 */
@Slf4j
@RestController
@RequestMapping("/fault/")
public class FaultServices {

	@Autowired
	private SuperDAO dao;
	@Autowired
	private FaultManager bm;
	@Autowired
	private FaultRecordQueryManager fqm;
	@Autowired
	private FaultRecordPersistManager fam;
	@Autowired
	private CimManager cm;
	@Autowired
	private MapDataCache cc;
	@Autowired
	private ParamManager pc;
	@Autowired
	private FaultFeedbackManager ffm;
	@Autowired
	private FaultSourcePersistManager fspm;
	@Autowired
	private EquipmentLedgerManager equipmentLedgerM;
	@Autowired
	private SubstationLedgerManager stationLedgerM;
	@Autowired
	private ResourcePermissFacde resourM;
	@Autowired
	private FaultWeatherInfoManager faultWeatherInfoManager;
	@Autowired
	private TravelingFaultRecordQueryManager travelingFaultRecordQueryManager;
	

	public static String[] etypes = new String[] { "母线", "线路", "变压器", "发电机" };
	public static String[] ranks = new String[] { "超高压公司", "调峰调频公司", "广东电网", "广州电网", "深圳电网", "广西电网", "云南电网", "贵州电网",
			"海南电网", "总调直调电厂 ", "广东中调电厂", "广州中调电厂", "深圳中调电厂", "广西中调电厂", "云南中调电厂", "贵州中调电厂", "海南中调电厂" };


	@GetMapping("/getLineFaultCountById/{id}")
	public String getLineFaultCountById(@PathVariable("id") String id) {
		List<FaultRecord> fs = new ArrayList<>();
		try {
			if (!StringUtils.isEmpty(id)) {
				fs = fqm.findFaultsByDeviceId(id);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
//		ConcurrentHashMap<String, SystemParameter> gifMap = pc.getMap().get(ParamDesc.GROUP_FAULT_REASON);
		List<SystemParameter> systemParameters = pc.listParamsByPid(ParamDesc.GROUP_FAULT_REASON);
		String other =pc.get(ParamDesc.FAULT_REASON_QT).getValue();
//		String other = gifMap.get(ParamDesc.FAULT_REASON_QT).getValue();
		for (FaultRecord f : fs) {
			String gif = null;
			for (SystemParameter g : systemParameters) {
				if (f.getFaultReson() != null && f.getFaultReson().equals(g.getDescription())) {
					gif = g.getValue();
				}
			}
			f.setGif(gif == null ? other : gif);
		}
		return JSONArray.fromObject(fs).toString();
	}

	/**
	 * 获取故障统计，按年，所属单位和类型
	 *
	 * 属于primaryfaultHis.xhtml，该页面已废弃
	 *
	 * @return [{year:[rank[{type,count}}]
	 */

	@GetMapping("/getFaultDatasByGroupYearRankType")
	public String getFaultDatasByGroupYearRankType() {
		String sql = "select t.faultTime,t.rank,t.etype from t_cim_fault t where t.voltage > 499 order by t.faultTime;";
		List<?> objs = dao.nativeQuery(sql);
		List<Integer> years = new ArrayList<>();
		Map<Integer, Map<String, Map<String, Integer>>> ydata = new HashMap<>();
		if (objs.size() > 0) {
			Object[] firstFault = (Object[]) objs.get(0);
			Timestamp d = (Timestamp) firstFault[0];
			String dstr = d.toString();// yyyy-mm-dd hh:mm:ss.fffffffff
			int fyear = Integer.valueOf(dstr.substring(0, 4));
			int currentYear = Calendar.getInstance().get(Calendar.YEAR);
			for (; fyear < currentYear + 1; fyear++) {
				Map<String, Map<String, Integer>> rd = new HashMap<>();
				for (String r : ranks) {
					Map<String, Integer> value = new HashMap<>();
					for (String t : etypes) {
						value.put(t, 0);
					}
					rd.put(r, value);
				}

				ydata.put(fyear, rd);
				years.add(fyear);
			}
		}
		for (Object o : objs) {
			Object[] os = (Object[]) o;
			Timestamp d = (Timestamp) os[0];
			String dstr = d.toString();// yyyy-mm-dd hh:mm:ss.fffffffff
			Integer year = Integer.valueOf(dstr.substring(0, 4));
			String rank = os[1].toString();
			String type = os[2].toString();
			Map<String, Map<String, Integer>> rs = ydata.get(year);
			if (rs != null) {
				Map<String, Integer> es = rs.get(rank);
				if (es != null) {
					Integer v = es.get(type);
					if (v != null)
						es.put(type, v + 1);
				}
			}
		}
		JSONArray datas = new JSONArray();
		for (Integer y : years) {
			JSONObject yd = new JSONObject();
			Map<String, Map<String, Integer>> rd = ydata.get(y);
			JSONArray rjs = new JSONArray();
			for (String r : ranks) {
				JSONObject rank = new JSONObject();
				Map<String, Integer> value = rd.get(r);
				JSONArray tjs = new JSONArray();
				for (String t : etypes) {
					JSONObject typecount = new JSONObject();
					typecount.put("name", t);
					typecount.put("value", value.get(t));
					tjs.add(typecount);
				}
				rank.put("name", r);
				rank.put("value", tjs);
				rjs.add(rank);
			}
			yd.put("name", y);
			yd.put("value", rjs);
			datas.add(yd);
		}

		return datas.toString();
	}

	/**
	 * 获取故障统计，按年月，所属单位和类型
	 *
	 * 属于primaryfaultHis.xhtml，该页面已废弃
	 *
	 * @return [{year:[rank[{type,count}}]
	 */

	@GetMapping("/getFaultDatasByGroupMonthRankType")
	public String getFaultDatasByGroupMonthRankType() {
		String sql = "select t.faultTime,t.rank,t.etype from t_cim_fault t where t.voltage = 500 order by t.faultTime;";
		List<?> objs = dao.nativeQuery(sql);
		List<Integer> years = new ArrayList<>();
		TreeSet<Integer> months = new TreeSet<>();
		Map<Integer, Map<Integer, Map<String, Map<String, Integer>>>> ydata = new HashMap<>();
		if (objs.size() > 0) {
			Object[] firstFault = (Object[]) objs.get(0);
			Timestamp d = (Timestamp) firstFault[0];
			String dstr = d.toString();// yyyy-mm-dd hh:mm:ss.fffffffff
			int fyear = Integer.valueOf(dstr.substring(0, 4));
			int currentYear = Calendar.getInstance().get(Calendar.YEAR);
			for (; fyear < currentYear + 1; fyear++) {
				Map<Integer, Map<String, Map<String, Integer>>> mdata = new HashMap<>();
				for (int fmonth = 1; fmonth <= 12; fmonth++) {
					Map<String, Map<String, Integer>> rd = new HashMap<>();
					for (String r : ranks) {
						Map<String, Integer> value = new HashMap<>();
						for (String t : etypes) {
							value.put(t, 0);
						}
						rd.put(r, value);
					}
					mdata.put(fmonth, rd);
					months.add(fmonth);
				}
				ydata.put(fyear, mdata);
				years.add(fyear);
			}
		}
		for (Object o : objs) {
			Object[] os = (Object[]) o;
			Timestamp d = (Timestamp) os[0];
			String dstr = d.toString();// yyyy-mm-dd hh:mm:ss.fffffffff
			Integer year = Integer.valueOf(dstr.substring(0, 4));
			Integer month = Integer.valueOf(dstr.substring(5, 7));
			String rank = os[1].toString();
			String type = os[2].toString();
			Map<Integer, Map<String, Map<String, Integer>>> ys = ydata.get(year);
			if (ys != null) {
				Map<String, Map<String, Integer>> ms = ys.get(month);
				if (ms != null) {
					Map<String, Integer> es = ms.get(rank);
					if (es != null) {
						Integer v = es.get(type);
						if (v != null) {
							v = v + 1;
							es.put(type, v);
						}
					}
				}
			}
		}
		JSONArray datas = new JSONArray();
		for (Integer y : years) {
			JSONObject yd = new JSONObject();
			Map<Integer, Map<String, Map<String, Integer>>> monthdata = ydata.get(y);
			JSONArray mjs = new JSONArray();
			for (Integer m : months) {
				JSONObject md = new JSONObject();
				Map<String, Map<String, Integer>> rankdata = monthdata.get(m);
				JSONArray rjs = new JSONArray();
				for (String r : ranks) {
					JSONObject rank = new JSONObject();
					Map<String, Integer> value = rankdata.get(r);
					JSONArray tjs = new JSONArray();
					for (String t : etypes) {
						JSONObject typecount = new JSONObject();
						typecount.put("name", t);
						typecount.put("value", value.get(t));
						tjs.add(typecount);
					}
					rank.put("name", r);
					rank.put("value", tjs);
					rjs.add(rank);
				}
				md.put("name", m);
				md.put("value", rjs);
				mjs.add(md);
			}
			yd.put("name", y);
			yd.put("value", mjs);
			datas.add(yd);
		}

		return datas.toString();
	}

	/**
	 * 获取故障统计，按年，所属单位和类型
	 *
	 * 用于FaultChartMan.js，用于在地图上展示故障的条形统计图，现已废弃
	 *
	 * @return [{rank:[type[{year,count}}]
	 */

	@GetMapping("/getFaultDatasByGroupRankTypeYear")
	public String getFaultDatasByGroupRankTypeYear() {
		String sql = "select t.faultTime,t.rank,t.etype from t_cim_fault t where t.voltage > 499 order by t.faultTime;";
		List<?> objs = dao.nativeQuery(sql);
		if (objs.size() == 0) {
			return "";
		}
		Map<String, Map<String, Map<String, Integer>>> result = new HashMap<>();

		for (Object o : objs) {
			Object[] os = (Object[]) o;
			String rank = os[1] == null ? "" : os[1].toString();
			String etype = os[2] == null ? "" : os[2].toString();
			if (os[0] == null) {
				continue;
			}
			Timestamp d = (Timestamp) os[0];
			Integer year = Integer.valueOf(d.toString().substring(0, 4));
			Map<String, Map<String, Integer>> rm = result.get(rank);
			if (rm == null) {
				rm = new HashMap<String, Map<String, Integer>>();
				result.put(rank, rm);
			}
			Map<String, Integer> tm = rm.get(etype);
			if (tm == null) {
				tm = new HashMap<String, Integer>();
				rm.put(etype, tm);
			}
			Integer tcount = tm.get(year);
			if (tcount == null) {
				tcount = 0;
			}
			tcount++;
			tm.put(year.toString(), tcount);
		}
		return JSONObject.fromObject(result).toString();
	}

	/**
	 * 暂时只找了线路的坐标去匹配。因为bx-fault表里面没有故障对应的变电站的id，无法找到变电站的坐标
	 * 如果能找到设备的坐标，那么设备名采用杆塔表或变电站表里的名，如果不能，就采用bx_fault里的名
	 *
	 * @param start
	 * @param end
	 * @return [[设备id，电网名，设备名，故障时间，经度，纬度,故障id],[],[]]
	 */

	@GetMapping("/getFaultByStartAndEnd/{start}/{end}")
	public String getFaultByStartAndEnd(@PathVariable("start") String start,@PathVariable("end") String end,
			HttpServletRequest request) {
		HttpSession session = request.getSession();
		Object obj = session.getAttribute("loginUser");
		PersonnelEntityBean user = null;
		if (obj instanceof PersonnelEntityBean) {
			user = (PersonnelEntityBean) obj;
		}
		// 找到故障列表
		Date s = DateUtil.getDateByString(start, DateUtil.pattern_ymd);
		Date e = DateUtil.getDateByString(end, DateUtil.pattern_ymd);
		Date cd = new Date();
		String cStr = DateUtil.getStringDate(cd, DateUtil.pattern_ymd);
		if (cStr.equals(end)) {
			e = cd;
		} else {
			Calendar c = Calendar.getInstance();
			c.setTime(e);
			c.add(Calendar.DAY_OF_YEAR, 1);
			c.add(Calendar.SECOND, -1);
			e = c.getTime();
		}
		List<FaultRecord> faults = null;
//		try {
//			faults = resourM.findGe500FaultByTime(user.getCode(), s, e);
			faults = resourM.findFaultByTime(user.getCode(),  s, e);   //主页--保护日报，查询所有故障（不止是500kV的）
			faults = fam.setupFaultLonAndLat(faults, true, false, true);
//		} catch (AuthorizationException e1) {

//			e1.printStackTrace();
//		}
		faults = initFaultDate(faults);
		return JSONArray.fromObject(faults).toString();

	}

	private List<FaultRecord> initFaultDate(List<FaultRecord> faults) {
		for (FaultRecord fault : faults) {
			String etype = fault.getEtype();
			String dispatchUnit = null;
			if (StringUtils.isNotEmpty(etype)) {
				if ("线路".equals(etype)) {
					PrimaryEquipmentLedger lineLedger = equipmentLedgerM
							.getEquipmentLedgerByEquipmentId(fault.getEquipment_id());
					if (null != lineLedger) {
						dispatchUnit = lineLedger.getDispatchUnit();
					}
				} else {
					SubstationLedger stationLedger = stationLedgerM.findSubstationLedger(fault.getStationId());
					if (null != stationLedger) {
						dispatchUnit = stationLedger.getDispatchUnit();
					}
				}
			}
			fault.setRank(dispatchUnit);
		}
		return faults;
	}

	private static ConcurrentHashMap<String,JSONObject> map_cache = new ConcurrentHashMap<>();

	@GetMapping("/getFaultByReasonAndDate/clear")
	public String getFaultByReasonAndDate() {
		map_cache.clear();
		return "OK";
	}
			
	/**
	 * 【故障分布】地图数据展示
	 *
	 * 将FaultRecord查询由使用SuperDAO改为使用 FaultRecordQueryManager查询
	 * 由于该类没有提供查询很多年份的同一个月份的方法，因此先查到很多年份的所有数据后，再根据月份进行的筛选。（20190109 zhangqi）
	 *
	 * @param startYear
	 * @param endYear
	 * @param reason
	 * @param month
	 * @return
	 */

	@GetMapping("/getFaultByReasonAndDate/{start}/{end}/{reason}/{month}")
	public String getFaultByReasonAndDate(@PathVariable("start") Integer startYear,@PathVariable("end") Integer endYear,
			@PathVariable("reason") String reason,@PathVariable("month") Integer month) {
		Date s = DateUtil.getDateByString(startYear + "-01-01", DateUtil.pattern_ymd);
		Date e = DateUtil.getDateByString((endYear + 1) + "-01-01", DateUtil.pattern_ymd);
		String datakey = startYear+"-"+endYear+"-"+reason+"-"+month;
		log.info(datakey);
		JSONObject result = map_cache.get(datakey);
		if(result != null) {
			return result.toString();
		}
		List<FaultRecord> fs = fqm.findFaultByTimeVoltageReason(s, e, 499, reason);
		List<FaultRecord> faults = new ArrayList<>();
		SimpleDateFormat dm = new SimpleDateFormat("M");
		String monthStr = month + "";
		if (month - 0 != 0) {
			for (FaultRecord f : fs) {
				if (f.getFaultTime() != null && monthStr.equals(dm.format(f.getFaultTime()))) {
					faults.add(f);
				}
			}
		} else {
			faults = fs;
		}
		fam.setupFaultLonAndLat(faults, true);
		result = new JSONObject();

		// 表格数据，按照设备发生故障的次数排序 [故障设备名，次数，是否在地图上找到位置]
		Map<String, Object[]> tableMap = new HashMap<>();
		// 热点图和热点网格图，以经纬度为key，如果出现重复的点，就微调经纬度。
		Map<String, Object[]> heatMap = new HashMap<>();
		// 散点图数据，以经纬度为key，如果出现重复的点，num就加一
		Map<String, Object[]> scatterMap = new HashMap<>();
		for (FaultRecord f : faults) {
			if (f.getEquipment() != null) {
				Object[] num = tableMap.get(f.getEquipment());
				if (num == null) {
					num = new Object[] { 1, f.getLon() == null ? 1 : 0, f.getEquipment_id() };
					tableMap.put(f.getEquipment(), num);
				} else {
					num[0] = Integer.parseInt(num[0].toString()) + 1;
					num[1] = Integer.parseInt(num[1].toString()) + (f.getLon() == null ? 1 : 0);
				}
			}
			if (f.getLat() != null && f.getLon() != null) {
				double lon = f.getLon();
				double lat = f.getLat();
				Object[] v = scatterMap.get(lon + "," + lat);
				if (v == null) {// 出现重复数据，就加一
					v = new Object[] { f.getLon(), f.getLat(), 1 };
					scatterMap.put(lon + "," + lat, v);
				} else {
					v[2] = (Integer) v[2] + 1;
				}
				Object[] v2 = heatMap.get(lon + "," + lat);
				while (v2 != null) {// 出现重复的经纬度，就微调经纬度
					lon = f.getLon() + 0.0000001 * Math.random();
					lat = f.getLat() + 0.0000001 * Math.random();
					v2 = heatMap.get(lon + lat);
				}
				v2 = new Object[] { lon, lat };
				heatMap.put(lon + "," + lat, v2);
			}
		}
		List<JSONObject> heatMapData = new ArrayList<>();
		for (Object[] et : heatMap.values()) {
			JSONObject o = new JSONObject();
			o.put("lon", et[0]);
			o.put("lat", et[1]);
			heatMapData.add(o);
		}
		result.put("heatMapData", heatMapData);
		List<JSONObject> scatterMapData = new ArrayList<>();
		for (Object[] et : scatterMap.values()) {
			JSONObject o = new JSONObject();
			o.put("lon", et[0]);
			o.put("lat", et[1]);
			o.put("radius", et[2]);
			scatterMapData.add(o);
		}
		result.put("scatterMapData", scatterMapData);

		List<Object[]> tableData = new ArrayList<>();
		for (Map.Entry<String, Object[]> et : tableMap.entrySet()) {
			tableData.add(new Object[] { et.getKey(), et.getValue()[0], et.getValue()[1], et.getValue()[2] });
		}
		Collections.sort(tableData, new Comparator<Object[]>() {
			@Override
			public int compare(Object[] o1, Object[] o2) {
				return -(int) o1[1] + (int) o2[1];
			}
		});
		
		result.put("tableData", tableData);
		map_cache.put(datakey, result);
		return result.toString();
	}


	@GetMapping("/getAlarmFault")
	public String getAlarmFault(HttpServletRequest request) {
		HttpSession session = request.getSession();
		Object obj = session.getAttribute("loginUser");
		PersonnelEntityBean user = null;
		if (obj instanceof PersonnelEntityBean) {
			user = (PersonnelEntityBean) obj;
		}
		if (user == null) {
			return "[]";
		}
		String num = pc.get(ParamDesc.FAULT_ALARM_SHOW_NUM).getValue();
		int n = NumberUtils.toInt(num);
		List<FaultRecord> fs = resourM.findLastestGe500kVFault(user.getCode(), n);
		// List<FaultRecord> fs = fqm.findLastestGe500kVFault(n);
		fam.setupFaultLonAndLat(fs, true, false, true);
		return JSONArray.fromObject(fs).toString();
	}

	/**
	 * 根据故障id获取故障信息，其中返回值中faultTime字段改为了String类型 该方法暂时无地方调用
	 *
	 * 将FaultRecord查询由使用SuperDAO改为使用 FaultRecordQueryManager查询 （20190109
	 * zhangqi）
	 *
	 * @param faultId
	 * @return
	 */

	@GetMapping("/getFaultsByFaultId/{faultId}")
	public String getFaultsByFaultId(@PathVariable("faultId") String faultId) {
		FaultRecord fault = fqm.findById(faultId);
		JSONObject o;
		if (fault != null) {
			o = JSONObject.fromObject(fault);
			o.put("faultTime", fault.getFaultTime() == null ? ""
					: DateUtil.getStringDate(fault.getFaultTime(), DateUtil.pattern_ymdhms));
		} else {
			o = new JSONObject();
		}
		return o.toString();
	}


	@GetMapping("/getFaultsByEquipmentId/{equipmentId}")
	public String getFaultsByEquipmentId(@PathVariable("equipmentId") String equipmentId) {
		List<FaultRecord> fault = fqm.findFaultsByDeviceId(equipmentId);
		return JSONArray.fromObject(fault).toString();
	}

	/**
	 * 【故障分布】罗列存在故障的月份
	 *
	 * 将FaultRecord查询由使用SuperDAO改为使用 FaultRecordQueryManager查询 （20190109
	 * zhangqi）
	 *
	 * @param reason
	 * @param startYear
	 * @param endYear
	 * @return
	 */

	@GetMapping("/getFaultMonthByReasonAndYear/{reason}/{startYear}/{endYear}")
	public String getFaultMonthByYear(@PathVariable("reason") String reason,@PathVariable("startYear") Integer startYear,
			@PathVariable("endYear") Integer endYear) {
		Calendar start = Calendar.getInstance();
		start.set(startYear, 0, 1, 0, 0, 0);
		Calendar end = Calendar.getInstance();
		end.set(endYear + 1, 0, 1, 0, 0, 0);
		List<FaultRecord> faults = fqm.findFaultByTimeVoltageReason(start.getTime(), end.getTime(), 499, reason);
		SimpleDateFormat df = new SimpleDateFormat("M");
		List<String> monthList = new ArrayList<>();
		for (FaultRecord f : faults) {
			if (f.getFaultTime() != null) {
				String m = df.format(f.getFaultTime());
				if (!monthList.contains(m)) {
					monthList.add(m);
				}
			}
		}
		return JSONArray.fromObject(monthList).toString();
	}


	@GetMapping("/getFaultsByReasonAndYearAndMonth/{reason}/{year}/{month}")
	public String getFaultsByReasonAndYearAndMonth(@PathVariable("reason") String reason,@PathVariable("year") Integer year,
			@PathVariable("month") Integer month) {
		Calendar start = Calendar.getInstance();
		start.set(year, month - 1, 1, 0, 0, 0);
		Calendar end = Calendar.getInstance();
		end.set(year, month, 1, 0, 0, 0);

		List<FaultRecord> faults = fqm.findFaultByTimeVoltageReason(start.getTime(), end.getTime(), 499, reason);
		fam.setupFaultLonAndLat(faults, true);
		return JSONArray.fromObject(faults).toString();
	}

	/**
	 * 往期电网故障反馈
	 *
	 * @param start
	 * @param end
	 * @return
	 */

	@GetMapping("/getFaultHisRebackByStartAndEnd/{start}/{end}")
	public String getFaultHisReback(@PathVariable("start") String start,@PathVariable("end") String end) {
		// 序号，调管范围，故障时间，故障设备，雷击定位系统记录，巡线结果，设备id，经度，纬度
		Date s = DateUtil.getDateByString(start, DateUtil.pattern_ymd);
		Date e = DateUtil.getDateByString(end, DateUtil.pattern_ymd);
		Calendar c = Calendar.getInstance();
		c.setTime(e);
		c.add(Calendar.DAY_OF_YEAR, 1);
		c.add(Calendar.SECOND, -1);
		e = c.getTime();
		List<FaultFeedback> res = ffm.findFaultFeedback(s, e);
		return JSONArray.fromObject(res).toString();
	}

	/**
	 * 用于更新故障的雷击信息，新的信息会覆盖原有的雷击信息
	 * @return
	 */

	@GetMapping("/updateFaultThunderInfo")
	public String updateFaultThunderInfo() {
		Calendar c = Calendar.getInstance();
		long s = c.getTimeInMillis();
		int startYear = 2007;
		int endYear = 2019;
		long ss = s;
		for (int i = startYear; i <= endYear; i++) {
			Date start = DateUtil.getDateByString(i + "-01-01 00:00:00", DateUtil.pattern_ymdhms);
			Date end = DateUtil.getDateByString(i + 1 + "-01-01 00:00:00", DateUtil.pattern_ymdhms);
			// faultWeatherInfoManager.updateFaultThunderInfo(start, end);
			long n = Calendar.getInstance().getTimeInMillis();
			log.info("完成，" + startYear + "年，耗时" + (n - ss) / 1000 + "秒");
			ss = n;
		}
		c = Calendar.getInstance();
		long e = c.getTimeInMillis() - s;
		log.info("完成，耗时" + e / 1000 + "秒");
		return "ok";
	}

	/**
	 * 【行波故障分布】地图数据展示
	 * @param startYear
	 * @param endYear
	 * @param month
	 * @return
	 */
	@GetMapping("/getTravelingFaultByDate/{start}/{end}/{month}")
	public String getTravelingFaultByDate(@PathVariable("start") Integer startYear,
			@PathVariable("end") Integer endYear,@PathVariable("month") Integer month) {
		//System.out.println("行波故障");
		Date s = DateUtil.getDateByString(startYear + "-01-01", DateUtil.pattern_ymd);
		Date e = DateUtil.getDateByString((endYear + 1) + "-01-01", DateUtil.pattern_ymd);
		List<TravelingWaveFaultRecord> fs = travelingFaultRecordQueryManager.getFaultRecordByDate(s, e);
		List<TravelingWaveFaultRecord> faults = new ArrayList<>();
		SimpleDateFormat dm = new SimpleDateFormat("M");
		String monthStr = month + "";
		if (month - 0 != 0) {
			for (TravelingWaveFaultRecord f : fs) {
				if (f.getPickTime() != null && monthStr.equals(dm.format(f.getPickTime()))) {
					faults.add(f);
				}
			}
		} else {
			faults = fs;
		}
		JSONObject result = new JSONObject();
		// 表格数据，按照设备发生故障的次数排序 [故障设备名，次数，是否在地图上找到位置]
		Map<String, Object[]> tableMap = new HashMap<>();
		// 热点图和热点网格图，以经纬度为key，如果出现重复的点，就微调经纬度。
		Map<String, Object[]> heatMap = new HashMap<>();
		// 散点图数据，以经纬度为key，如果出现重复的点，num就加一
		Map<String, Object[]> scatterMap = new HashMap<>();
		//获取变电站缓存数据
		HashMap<String, Substation> stationid_map = cc.getStationid_map();
		for (TravelingWaveFaultRecord f : faults) {
			if (f.getLineId() != null) {
				Object[] num = tableMap.get(f.getLineName());
				if (num == null) {
					num = new Object[] { 1, 1, f.getLineId() };
					tableMap.put(f.getLineName(), num);
				} else {
					num[0] = Integer.parseInt(num[0].toString()) + 1;
					num[1] = Integer.parseInt(num[1].toString()) + 1;
				}
			}
			if(StringUtils.isNotEmpty(f.getLocalStationId())) {
				Substation substaion = stationid_map.get(f.getLocalStationId());
				Double longitude = substaion.getLongitude();
				Double latitude = substaion.getLatitude();
				//获取本端变电站经纬度
				Object[] v = scatterMap.get(longitude + "," + latitude);
				// 出现重复数据，就加一
				if (v == null) {
					v = new Object[] { longitude, latitude, 1 };
					scatterMap.put(longitude + "," + latitude, v);
				} else {
					v[2] = (Integer) v[2] + 1;
				}
				Object[] v2 = heatMap.get(longitude + "," + latitude);
				// 出现重复的经纬度，就微调经纬度
				while (v2 != null && longitude != null && latitude != null) {
					longitude = longitude + 0.0000001 * Math.random();
					latitude = latitude + 0.0000001 * Math.random();
					v2 = heatMap.get(longitude +","+ latitude);
				}
				v2 = new Object[] { longitude, latitude };
				heatMap.put(longitude + "," + latitude, v2);
			}
			if(StringUtils.isNotEmpty(f.getPeerStationId())) {
				Substation substaion = stationid_map.get(f.getPeerStationId());
				
				if (substaion != null) {
					Double longitude = substaion.getLongitude();
					Double latitude = substaion.getLatitude();
					
					if (longitude != null && latitude !=null) {
						//获取本端变电站经纬度
						Object[] v = scatterMap.get(longitude + "," + latitude);
						// 出现重复数据，就加一
						if (v == null) {
							v = new Object[] { longitude, latitude, 1 };
							scatterMap.put(longitude + "," + latitude, v);
						} else {
							v[2] = (Integer) v[2] + 1;
						}
						Object[] v2 = heatMap.get(longitude + "," + latitude);
						// 出现重复的经纬度，就微调经纬度
						while (v2 != null && longitude != null && latitude != null) {
							longitude = longitude + 0.0000001 * Math.random();
							latitude = latitude + 0.0000001 * Math.random();
							v2 = heatMap.get(longitude +","+ latitude);
						}
						v2 = new Object[] { longitude, latitude };
						heatMap.put(longitude + "," + latitude, v2);
					}
				}else {
					System.out.println("-------------------------->变电站为空！");
				}
			}
		}
		List<JSONObject> heatMapData = new ArrayList<>();
		for (Object[] et : heatMap.values()) {
			JSONObject o = new JSONObject();
			o.put("lon", et[0]);
			o.put("lat", et[1]);
			heatMapData.add(o);
		}
		result.put("heatMapData", heatMapData);
		List<JSONObject> scatterMapData = new ArrayList<>();
		for (Object[] et : scatterMap.values()) {
			JSONObject o = new JSONObject();
			o.put("lon", et[0]);
			o.put("lat", et[1]);
			o.put("radius", et[2]);
			scatterMapData.add(o);
		}
		result.put("scatterMapData", scatterMapData);
		List<Object[]> tableData = new ArrayList<>();
		for (Map.Entry<String, Object[]> et : tableMap.entrySet()) {
			tableData.add(new Object[] { et.getKey(), et.getValue()[0], et.getValue()[1], et.getValue()[2] });
		}
		Collections.sort(tableData, new Comparator<Object[]>() {
			@Override
			public int compare(Object[] o1, Object[] o2) {
				return -(int) o1[1] + (int) o2[1];
			}
		});
		result.put("tableData", tableData);
		return result.toString();
	}

	/**
	 * 【行波故障分布】罗列存在行波故障的月份
	 *
	 * @param startYear
	 * @param endYear
	 * @return
	 */
	@GetMapping("/getTravelingFaultMonthByYear/{startYear}/{endYear}")
	public String getTravelingFaultMonthByYear(@PathVariable("startYear") Integer startYear,@PathVariable("endYear") Integer endYear) {
		Calendar start = Calendar.getInstance();
		start.set(startYear, 0, 1, 0, 0, 0);
		Calendar end = Calendar.getInstance();
		end.set(endYear + 1, 0, 1, 0, 0, 0);
		List<TravelingWaveFaultRecord> faults = travelingFaultRecordQueryManager.getFaultRecordByDate(start.getTime(), end.getTime());
		SimpleDateFormat df = new SimpleDateFormat("M");
		List<String> monthList = new ArrayList<>();
		for (TravelingWaveFaultRecord f : faults) {
			if (f.getPickTime() != null) {
				String m = df.format(f.getPickTime());
				if (!monthList.contains(m)) {
					monthList.add(m);
				}
			}
		}
		return JSONArray.fromObject(monthList).toString();
	}


}
